#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include <sys/time.h>
#include <pthread.h>
#include <sqltypes.h>
#define MESSAGE_BUFFER_LEN  512
void print_error();
void end_unit_test();
int execute_cmd(SQLCHAR *sql);
int commit_exec();
/* ------------------------- 测试用常量宏定义 ------------------------------- */

#define STRING_DSN          "og"

SQLHANDLE   h_env = NULL;
SQLHANDLE   h_conn = NULL;


/* 期盼函数返回SQL_SUCCESS */
#define RETURN_IF_NOT_SUCCESS(func) \
{\
    SQLRETURN ret_value = (func);\
    if (SQL_SUCCESS != ret_value)\
    {\
        print_error();\
        printf("\n failed line = %u: expect SQL_SUCCESS, but ret = %d", __LINE__, ret_value);\
        return SQL_ERROR; \
    }\
}


SQLCHAR*    sql_drop   = "drop table if exists test_bindnumber_001";
SQLCHAR*    sql_create = "create table test_bindnumber_001(f4 number, f5 number(10, 2),age timestamp without time zone)";
SQLCHAR*    sql_insert = "insert into t1 values(2)";
SQLCHAR*    sql_select = "select 1 ";
        

void testconnnection()
{
        SQLHANDLE   h_stmt = NULL;
        /* 查询 */
        RETURN_IF_NOT_SUCCESS(SQLAllocHandle(SQL_HANDLE_STMT, h_conn, &h_stmt));
        RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_select, SQL_NTS));
        SQLExecute(h_stmt);
        SQLFreeHandle(SQL_HANDLE_STMT, h_stmt);
        // SQLEndTran(SQL_HANDLE_DBC, h_conn, SQL_COMMIT);
}

int main()
{
        int         i = 0;
        SQLHANDLE   h_stmt = NULL;
        /* 申请环境句柄 */
        RETURN_IF_NOT_SUCCESS(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &h_env));
        /* 进行连接前必须要先设置版本号 */
        RETURN_IF_NOT_SUCCESS(SQLSetEnvAttr(h_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
        /* 申请连接句柄 */
        RETURN_IF_NOT_SUCCESS(SQLAllocHandle(SQL_HANDLE_DBC, h_env, &h_conn));
        /* 关闭手动提交 */
        RETURN_IF_NOT_SUCCESS(SQLSetConnectAttr(h_conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0));
        /* 建立连接 */
        RETURN_IF_NOT_SUCCESS(SQLConnect(h_conn, STRING_DSN, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS));



       testconnnection();


        /* 插入 */
        SQLAllocHandle(SQL_HANDLE_STMT, h_conn, &h_stmt);
        SQLPrepare(h_stmt, sql_insert, SQL_NTS);
        SQLExecute(h_stmt);
        SQLFreeHandle(SQL_HANDLE_STMT, h_stmt);
        SQLEndTran(SQL_HANDLE_DBC, h_conn, SQL_COMMIT);


        while(1) {
        }
        // end_unit_test();
}




/*****************************************************************************
 *  *  函 数 名  : print_error
 *   *  功能描述  : 打印连接上的错误信息
 *    *  输出参数  : 无
 *     *  返 回 值  : int
 *      *  *****************************************************************************/

void print_error() {
        SQLCHAR     Sqlstate[SQL_SQLSTATE_SIZE+1];
        SQLINTEGER  NativeError;
        SQLCHAR     MessageText[MESSAGE_BUFFER_LEN];
        SQLSMALLINT TextLength;
        SQLRETURN   ret = SQL_ERROR;
        ret = SQLGetDiagRec(SQL_HANDLE_STMT, h_stmt, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength);
        if ( SQL_SUCCESS == ret)    {
                printf("\n STMT ERROR-%05d %s", NativeError, MessageText);
                return;    }
        ret = SQLGetDiagRec(SQL_HANDLE_DBC, h_conn, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength);
        if ( SQL_SUCCESS == ret)    {
                printf("\n CONN ERROR-%05d %s", NativeError, MessageText);
                return;    }
        ret = SQLGetDiagRec(SQL_HANDLE_ENV, h_env, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength);
        if ( SQL_SUCCESS == ret)    {
                printf("\n ENV ERROR-%05d %s", NativeError, MessageText);
                return;
        }
        return;
}
void print_diag(char *msg, SQLSMALLINT htype, SQLHANDLE handle)
{
        char sqlstate[32];
        char message[1000];
        SQLINTEGER nativeerror;
        SQLSMALLINT textlen;
        SQLRETURN ret;
        if (msg)
                printf("%s\n", msg);
        ret = SQLGetDiagRec(htype, handle, 1, sqlstate, &nativeerror,
                                                message, 256, &textlen);
        if (ret != SQL_ERROR)
                printf("%s=%s\n", (CHAR *)sqlstate, (CHAR *)message);
}

void print_result(HSTMT hstmt)
{
        SQLRETURN rc;
        SQLSMALLINT numcols;
        rc = SQLNumResultCols(hstmt, &numcols);
        if (!SQL_SUCCEEDED(rc)){
                print_diag("SQLNumResultCols failed", SQL_HANDLE_STMT, hstmt);
                return;
        }
        printf("Result set:\n");
        while(1)
        {
                rc = SQLFetch(hstmt);
                if (rc == SQL_NO_DATA)
                        break;
                if (rc == SQL_SUCCESS){
                        char buf[200];
                        int i;
                        SQLLEN ind;

                        for (i = 1; i <= numcols; i++)
                        {
                                rc = SQLGetData(hstmt,i, SQL_C_CHAR, buf, sizeof(buf), &ind);
                                if (!SQL_SUCCEEDED(rc)){
                                        print_diag("SQLGetData failed", SQL_HANDLE_STMT, hstmt);
                                        return;
                                }
                                if (ind == SQL_NULL_DATA)
                                        strcpy(buf, "NULL");
                                printf("%s%s", (i > 1) ? "\t" : "", buf);
                        }
                        printf("\n");
                }
                else{
                        print_diag("SQLFetch failed", SQL_HANDLE_STMT, hstmt);
                        exit(1);
                }
        }
}
int commit_exec() {
        if ( SQL_SUCCESS != SQLExecute(h_stmt)){
                return SQL_ERROR;
        }
        return SQL_SUCCESS;
}

int execute_cmd(SQLCHAR *sql) {
        if ( NULL == sql ){
                return SQL_ERROR;
        }
        if ( SQL_SUCCESS != SQLPrepare(h_stmt, sql, SQL_NTS)){
                print_diag(" SQLPrepare failed.", SQL_HANDLE_STMT, h_stmt);
                return SQL_ERROR;
        }
        if ( SQL_SUCCESS != SQLExecute(h_stmt)){
                print_diag(" SQLExecute failed.", SQL_HANDLE_STMT, h_stmt);
                return SQL_ERROR;
        }
        return SQL_SUCCESS;
}
void end_unit_test() {
        /* 释放语句句柄 */
        if (NULL != h_stmt){
                SQLFreeHandle(SQL_HANDLE_STMT, h_stmt);
        }
        /* 释放连接句柄 */
        if (NULL != h_conn){
                SQLDisconnect(h_conn);
                SQLFreeHandle(SQL_HANDLE_DBC, h_conn);
        }
        /* 释放环境句柄 */
        if (NULL != h_env){
                SQLFreeHandle(SQL_HANDLE_ENV, h_env);
        }
        return;
}
